using System;
using System.Runtime.InteropServices;

namespace Leap
{
	public class Screen : Interface
	{
		private HandleRef swigCPtr;

		public int Id => LeapPINVOKE.Screen_Id_get(swigCPtr);

		public Vector HorizontalAxis
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Screen_HorizontalAxis_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Vector(intPtr, true);
			}
		}

		public Vector VerticalAxis
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Screen_VerticalAxis_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Vector(intPtr, true);
			}
		}

		public Vector BottomLeftCorner
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Screen_BottomLeftCorner_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Vector(intPtr, true);
			}
		}

		public int WidthPixels => LeapPINVOKE.Screen_WidthPixels_get(swigCPtr);

		public int HeightPixels => LeapPINVOKE.Screen_HeightPixels_get(swigCPtr);

		public bool IsValid => LeapPINVOKE.Screen_IsValid_get(swigCPtr);

		public static Screen Invalid => new Screen(LeapPINVOKE.Screen_Invalid_get(), false);

		public Screen(IntPtr cPtr, bool cMemoryOwn)
			: base(LeapPINVOKE.Screen_SWIGUpcast(cPtr), cMemoryOwn)
		{
			swigCPtr = new HandleRef(this, cPtr);
		}

		public static HandleRef getCPtr(Screen obj)
		{
			return obj?.swigCPtr ?? new HandleRef(null, IntPtr.Zero);
		}

		~Screen()
		{
			Dispose();
		}

		public override void Dispose()
		{
			lock (this)
			{
				if (swigCPtr.Handle != IntPtr.Zero)
				{
					if (base.swigCMemOwn)
					{
						base.swigCMemOwn = false;
						LeapPINVOKE.delete_Screen(swigCPtr);
					}
					swigCPtr = new HandleRef(null, IntPtr.Zero);
				}
				GC.SuppressFinalize(this);
				base.Dispose();
			}
		}

		public Screen()
			: this(LeapPINVOKE.new_Screen(), true)
		{
		}

		public Vector Intersect(Pointable pointable, bool normalize, float clampRatio)
		{
			Vector result = new Vector(LeapPINVOKE.Screen_Intersect__SWIG_0(swigCPtr, Pointable.getCPtr(pointable), normalize, clampRatio), true);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public Vector Intersect(Pointable pointable, bool normalize)
		{
			Vector result = new Vector(LeapPINVOKE.Screen_Intersect__SWIG_1(swigCPtr, Pointable.getCPtr(pointable), normalize), true);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public Vector Intersect(Vector position, Vector direction, bool normalize, float clampRatio)
		{
			Vector result = new Vector(LeapPINVOKE.Screen_Intersect__SWIG_2(swigCPtr, Vector.getCPtr(position), Vector.getCPtr(direction), normalize, clampRatio), true);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public Vector Intersect(Vector position, Vector direction, bool normalize)
		{
			Vector result = new Vector(LeapPINVOKE.Screen_Intersect__SWIG_3(swigCPtr, Vector.getCPtr(position), Vector.getCPtr(direction), normalize), true);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public Vector Project(Vector position, bool normalize, float clampRatio)
		{
			Vector result = new Vector(LeapPINVOKE.Screen_Project__SWIG_0(swigCPtr, Vector.getCPtr(position), normalize, clampRatio), true);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public Vector Project(Vector position, bool normalize)
		{
			Vector result = new Vector(LeapPINVOKE.Screen_Project__SWIG_1(swigCPtr, Vector.getCPtr(position), normalize), true);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public Vector Normal()
		{
			return new Vector(LeapPINVOKE.Screen_Normal(swigCPtr), true);
		}

		public float DistanceToPoint(Vector point)
		{
			float result = LeapPINVOKE.Screen_DistanceToPoint(swigCPtr, Vector.getCPtr(point));
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public bool Equals(Screen arg0)
		{
			bool result = LeapPINVOKE.Screen_Equals(swigCPtr, getCPtr(arg0));
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public override string ToString()
		{
			return LeapPINVOKE.Screen_ToString(swigCPtr);
		}
	}
}
